<script lang="ts" setup name="DataFunTable">
import { ref } from 'vue'
import { CirclePlus, Delete, SortDown, SortUp, WarningFilled } from '@element-plus/icons-vue'
import { _ } from 'iking-utils'
import { useFormRules } from '@g/hooks/use-rules'
import type { addFieldsForm } from '../interface'
import {
  getfieldTypeList,
  getJavaType
} from '@/MainApp/apis/manage-design'

const props = defineProps({
  tableData: {
    type: Object,
    default: () => null
  },
  primaryField: {
    type: Array<any>,
    default: () => []
  }
})
const { msgBoxWarning, msgError } = useMessage()
const { lenName } = useLength()
const addTableFormRef = ref()
const addFieldsFormData = ref<addFieldsForm>({
  domainObjectClassName: props.tableData?.domainObjectClassName || '',
  domainTransferObjectClassName:
    props.tableData?.domainTransferObjectClassName || ''
})
const fieldsData = ref(props.tableData?.fields || [])
const fieldsRules = useFormRules([
  {
    key: 'domainObjectClassName',
    required: true,
    trigger: 'blur',
    msg: '请输入数据映射类名'
  },
  {
    key: 'domainTransferObjectClassName',
    required: true,
    trigger: 'blur',
    msg: '请输入工程包名'
  }
])
const tableFieldList = ref<Array<any>>([])
const javaFieldList = ref<Array<any>>([])
watch(
  () => props.tableData,
  () => {
    if (props.tableData) {
      fieldsData.value = _.cloneDeep(props.tableData.fields)

      addFieldsFormData.value = {
        domainObjectClassName: props.tableData.domainObjectClassName || '',
        domainTransferObjectClassName:
          props.tableData.domainTransferObjectClassName || ''
      }
    }
  }
)
const addFields = () => {
  fieldsData.value.push({
    comment: '',
    domainObjectFieldName: '',
    domainObjectFieldType: '',
    domainTransferObjectFieldName: '',
    domainTransferObjectFieldType: '',
    foreignFieldId: '',
    id: '',
    moduleId: '',
    nullField: false,
    projectId: '',
    tableFieldLength: '',
    tableFieldName: '',
    tableFieldType: '',
    tableId: '',
    tableName: ''
  })
}
// 删除
const handDelete = (row: any, index: any) => {
  msgBoxWarning('确认删除', '确认删除该字段吗?', async () => {
    fieldsData.value.splice(index, 1)
  })
}
const getFileds = async () => {
  const { success, data } = await getfieldTypeList()
  if (success) {
    tableFieldList.value = data.tableFieldTypeList
    javaFieldList.value = data.javaFieldTypeList
  }
}
getFileds()
const getDataTable = async () => {
  await addTableFormRef.value.validate((valid: any) => {
    if (!valid)
      return false
  })
  if (fieldsData.value.length === 0) {
    msgError(`请添加表字段  ::检查${props.tableData.tableName}表`)
    return false
  }
  try {
    fieldsData.value.forEach((item: any, index: any) => {
      if (item.tableFieldName === '')
        throw new Error('请填写字段名称')

      // if (item.tableFieldLength === '') throw new Error('请填写字段长度')

      if (item.tableFieldType === '')
        throw new Error('请选择字段类型')

      if (item.domainObjectFieldName === '')
        throw new Error('请填写映射字段')

      if (item.domainObjectFieldType === '')
        throw new Error('请选择映射字段类型')

      if (
        props.tableData.isPrimary
        && item.domainTransferObjectFieldName === ''
      )
        throw new Error('请填写传输字段')

      if (
        props.tableData.isPrimary
        && item.domainTransferObjectFieldType === ''
      )
        throw new Error('请选择传输字段类型')
      for (let i = index + 1; i < fieldsData.value.length; i++) {
        if (item.tableFieldName === fieldsData.value[i].tableFieldName)
          throw new Error('字段名称不能重复')

        if (
          item.domainObjectFieldName
          === fieldsData.value[i].domainObjectFieldName
        )
          throw new Error('映射字段名称不能重复')

        if (
          props.tableData.isPrimary
          && item.domainTransferObjectFieldName
            === fieldsData.value[i].domainTransferObjectFieldName
        )
          throw new Error('传输字段名称不能重复')
      }
    })
  }
  catch (e) {
    msgError(`${e}  ::检查${props.tableData.tableName}表`)
    return false
  }
  return {
    ...addFieldsFormData.value,
    fields: _.cloneDeep(fieldsData.value)
  }
}
const getData = () => {
  return {
    ...props.tableData,
    ...addFieldsFormData.value,
    fields: _.cloneDeep(fieldsData.value)
  }
}
const changeName = (value: any, row: any, index: any) => {
  let domainObjectFieldName = ''
  if (value.target && value.target.value) {
    const name = value.target.value.split('_')
    name.forEach((ele: string) => {
      domainObjectFieldName += ele.replace(ele[0], ele[0]?.toUpperCase() || '')
    })
    domainObjectFieldName = domainObjectFieldName.replace(
      domainObjectFieldName[0],
      domainObjectFieldName[0]?.toLowerCase() || ''
    )
    fieldsData.value[index].domainObjectFieldName = domainObjectFieldName
    fieldsData.value[index].domainTransferObjectFieldName
      = domainObjectFieldName
  }
}
const changeFieldType = async (value: any, index: any) => {
  const { data, success } = await getJavaType(value)
  if (success) {
    fieldsData.value[index].domainObjectFieldType = data
    fieldsData.value[index].domainTransferObjectFieldType = data
  }
}
const handSortDown = (row: any, index: any) => {
  if (index !== fieldsData.value.length - 1) {
    fieldsData.value.splice(index, 1)
    fieldsData.value.splice(index + 1, 0, row)
  }
}
const handSortUp = (row: any, index: any) => {
  if (index !== 0) {
    fieldsData.value.splice(index, 1)
    fieldsData.value.splice(index - 1, 0, row)
  }
}
defineExpose({
  getDataTable,
  getData
})
</script>

<template>
  <div>
    <el-form
      ref="addTableFormRef"
      :model="addFieldsFormData"
      :rules="fieldsRules"
      label-width="120px"
    >
      <el-row class="elcol-top">
        <el-col :span="12" class="elcol">
          <el-form-item label="数据映射类名" prop="domainObjectClassName">
            <el-input
              v-model.trim="addFieldsFormData.domainObjectClassName"
              clearable
              :maxlength="lenName"
              show-word-limit
              placeholder="请输入数据映射类名"
            />
          </el-form-item>
        </el-col>
        <el-col v-if="props.tableData.isPrimary" :span="12" class="elcol">
          <el-form-item
            label="数据传输类名"
            prop="domainTransferObjectClassName"
          >
            <el-input
              v-model.trim="addFieldsFormData.domainTransferObjectClassName"
              :maxlength="lenName"
              show-word-limit
              placeholder="请输入数据传输类名"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <el-row>
      <el-col v-if="props.tableData.newTable" :span="24" class="text-cen">
        <p>
          <el-icon><WarningFilled /></el-icon>
          提示：创建表或定义表时，系统会默认为表创建7个字段：主键(id)、创建时间(create_time)、创建人编号(create_by)、创建人姓名(create_name)、更新时间(update_time)、更新人编号(update_by)、更新人姓名(update_name)。您可以点击预览SQL按钮，查看详细信息。
          注意！主键、创建人编号、更新人编号的数据类型为VARCHAR，长度32；创建人姓名、更新人姓名的数据类型为VARCHAR，长度64；创建时间、更新时间的数据类型为DATETIME。
        </p>
      </el-col>
      <el-col :span="24" class="table-cen">
        <el-table :data="fieldsData">
          <el-table-column type="index" width="80" label="序号" />
          <el-table-column label="数据库">
            <el-table-column prop="tableFieldName" label="字段名称">
              <template #default="{ row, $index }">
                <el-input
                  v-model.trim="row.tableFieldName"
                  :disabled="!props.tableData.newTable || row.isDefault"
                  placeholder="请输入字段名称"
                  @blur="changeName($event, row, $index)"
                />
              </template>
            </el-table-column>

            <el-table-column prop="tableFieldType" label="字段类型" width="140">
              <template #default="{ row, $index }">
                <el-select
                  v-model="row.tableFieldType"
                  :disabled="!props.tableData.newTable || row.isDefault"
                  placeholder="请选择字段类型"
                  @change="changeFieldType($event, $index)"
                >
                  <el-option
                    v-for="(item, index) in tableFieldList"
                    :key="index"
                    :label="item"
                    :value="item"
                  />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column prop="tableFieldLength" label="字段长度" width="100">
              <template #default="{ row }">
                <el-input
                  v-model.trim="row.tableFieldLength"
                  :disabled="!props.tableData.newTable || row.isDefault"
                  placeholder="请输入..."
                />
              </template>
            </el-table-column>
            <el-table-column prop="nullField" label="允许空值" width="90">
              <template #default="{ row }">
                <el-checkbox
                  v-model="row.nullField"
                  :disabled="!props.tableData.newTable || row.isDefault"
                  size="large"
                />
              </template>
            </el-table-column>
            <el-table-column
              v-if="!props.tableData.isPrimary"
              prop="comment"
              label="关联字段"
            >
              <template #default="{ row }">
                <el-select
                  v-model="row.foreignFieldId"
                  placeholder="请选择关联字段"
                  clearable
                >
                  <el-option
                    v-for="(item, index) in props.primaryField"
                    :key="index"
                    :label="item.tableFieldName"
                    :value="item.tableFieldName"
                  />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column prop="comment" label="注释">
              <template #default="{ row }">
                <el-input
                  v-model.trim="row.comment"
                  :disabled="!props.tableData.newTable || row.isDefault"
                  placeholder="请输入注释"
                />
              </template>
            </el-table-column>
          </el-table-column>
          <el-table-column label="数据映射">
            <el-table-column prop="domainObjectFieldName" label="映射字段名">
              <template #default="{ row }">
                <el-input
                  v-model.trim="row.domainObjectFieldName"
                  :disabled="!props.tableData.newTable || row.isDefault"
                  placeholder="请输入映射字段名"
                />
              </template>
            </el-table-column>
            <el-table-column prop="domainObjectFieldType" label="映射字段类型">
              <template #default="{ row }">
                <el-select
                  v-model="row.domainObjectFieldType"
                  :disabled="!props.tableData.newTable || row.isDefault"
                  placeholder="请选择映射字段类型"
                >
                  <el-option
                    v-for="(item, index) in javaFieldList"
                    :key="index"
                    :label="item"
                    :value="item"
                  />
                </el-select>
              </template>
            </el-table-column>
          </el-table-column>
          <el-table-column v-if="props.tableData.isPrimary" label="数据传输">
            <el-table-column
              prop="domainTransferObjectFieldName"
              label="传输字段名称"
            >
              <template #default="{ row }">
                <el-input
                  v-model.trim="row.domainTransferObjectFieldName"
                  :disabled="!props.tableData.newTable || row.isDefault"
                  placeholder="请输入传输字段名称"
                />
              </template>
            </el-table-column>
            <el-table-column
              prop="domainTransferObjectFieldType"
              label="传输字段类型"
            >
              <template #default="{ row }">
                <el-select
                  v-model="row.domainTransferObjectFieldType"
                  :disabled="!props.tableData.newTable || row.isDefault"
                  placeholder="请选择映射字段类型"
                >
                  <el-option
                    v-for="(item, index) in javaFieldList"
                    :key="index"
                    :label="item"
                    :value="item"
                  />
                </el-select>
              </template>
            </el-table-column>
          </el-table-column>
          <el-table-column
            v-if="props.tableData.newTable"
            label="操作"
            fixed="right"
            width="200"
          >
            <template #default="{ row, $index }">
              <IkBtnContent :num="7">
                <el-button
                  type="danger"
                  :icon="Delete"
                  text
                  @click="handDelete(row, $index)"
                >
                  删除
                </el-button>
                <el-button
                  type="primary"
                  :icon="SortDown"
                  text
                  @click="handSortDown(row, $index)"
                />
                <el-button
                  type="primary"
                  :icon="SortUp"
                  text
                  @click="handSortUp(row, $index)"
                />
              </IkBtnContent>
            </template>
          </el-table-column>
        </el-table>
        <el-row v-if="props.tableData.newTable">
          <el-col :span="24">
            <div class="addTablebtn" @click="addFields">
              <CirclePlus style="width: 1em; height: 1em; margin-right: 8px;" />
              <span>添加字段</span>
            </div>
          </el-col>
        </el-row>
      </el-col>
    </el-row>
  </div>
</template>

<style lang="scss" scoped>
.elcol-top {
  margin: 15px 0;
}

.text-cen{
  color: rgb(243 176 60);
  background-color: rgb(253 250 232);
  margin-bottom: 15px;
  display: flex;
  align-items: center;
  padding: 5px 10px;
}

.table-cen{
  min-height: 500px;
}

.addTablebtn {
  margin: 20px 0;
  padding: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed #e5e5e5;
}

.cell-cen {
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
